﻿using System;
using System.Collections.Generic;
using System.Linq;

using System.Threading;
using orienta.Models;
using System.Diagnostics;
using System.Net.Mail;
using System.Text;
using System.Configuration;

using orienta.ViewModels;

namespace orienta.Helper
{
    public class EmailHelper
    {


        private GoodTireEntities db = new GoodTireEntities();

        public void InciarWorkerThreadEnvioMail()
        {
           

           
            //while (true)
            //{
                var task = new Thread(() => SendEmail());
                task.Name = "GenerarEnvioMail";
                task.IsBackground = true;
                 Trace.TraceInformation("MAIL: INICIANDO envio de Mail " + DateTime.Now);
               // Thread.Sleep(50000);
            
                task.Start();
            //}


        }


        public void SendEmail()
        {
            DateTime dia = DateTime.Now;
            String subject = "Reporte de alertas al " + String.Format("{0:dd/MM/yyyy HH:mm}", dia);
            int correos = 0;

            while (true)
            {
                Thread.Sleep(10000);

                //                if (esDomingo() && corrioServicio())
                if (esDomingo() && !corrioServicio())
                {

                    try
                    {

                        List<ORIDetCompendio> lista = db.ORIDetCompendio.Where(o => o.nIdeCompendio == CatalogoHelper._JEFES_TRAMITES).ToList();
                        List<ORIDetCompendio> listaPlazos = db.ORIDetCompendio.Where(o => o.nIdeCompendio == CatalogoHelper._TIPO_SOLICITUD_PLAZOS).ToList();

                        foreach (ORIDetCompendio compendio in lista)
                        {
                            int area = Int32.Parse(compendio.vCodElemento);

                            String html = obtenerHTML(area, listaPlazos);


                            string dominio = ConfigurationManager.AppSettings["dominio"];
                            string correo = ConfigurationManager.AppSettings["correo"];
                            string puerto = ConfigurationManager.AppSettings["puerto"];
                            string clave = ConfigurationManager.AppSettings["clave"];


                            SmtpClient client = new SmtpClient();
                            client.Port = Int32.Parse(puerto);// puerto87;
                            client.Host = dominio;// "smtp.gmail.com";
                            client.EnableSsl = true;
                            client.Timeout = 10000;
                            client.DeliveryMethod = SmtpDeliveryMethod.Network;
                            client.UseDefaultCredentials = false;
                            client.Credentials = new System.Net.NetworkCredential(correo, clave);

                            MailMessage mm = new MailMessage(correo, compendio.vDesRef2, subject, html);
                          //  MailMessage mm = new MailMessage(correo, "mivalle@gmail.com", subject, html);
                            // mm.BodyEncoding = UTF8Encoding.UTF8;
                            mm.IsBodyHtml = true;
                            mm.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;

                            client.Send(mm);

                            correos++;

                        }

                        actualizarLogAlerta(correos);
                    }
                    catch (Exception e) {

                        try
                        {
                            ORIMaeLogError err = new ORIMaeLogError();
                            err.dFecReg = DateTime.Today;
                            err.vCodError = "EmailHelper";
                            err.vDescError = e.ToString().Substring(0,49);
                            err.nIdeUsuReg = 0;
                            err.vParametros = ConfigurationManager.AppSettings.ToString();

                            err.vURL = "Web.Config";
                            //            alerta.
                            db.ORIMaeLogError.AddObject(err);
                            db.SaveChanges();
                        }
                        catch (Exception e1) {
                            String eeee = e1.ToString();
                        }
                    }
                }
            }
        }

        private Boolean esDomingo() {
            string diaSemana = ConfigurationManager.AppSettings["diaSemana"];
                
            DateTime dia = DateTime.Now;
            DayOfWeek dayOfWeek = dia.DayOfWeek;
            if (dayOfWeek.ToString().Equals(diaSemana))
                return true;
            else return false;

        
        }

        private Boolean corrioServicio()
        {
            DateTime hoy = DateTime.Now;
            try
            {
                ORIMaeLogAlerta alerta = db.ORIMaeLogAlerta.Single(o => o.dFecReg.Day == hoy.Day && o.dFecReg.Month == hoy.Month && o.dFecReg.Year == hoy.Year);
                Object o1 = alerta;
                //            ORIMaeLogAlerta dependencia = db.ORIMaeDependencia.Single(o => o.nIdeDep == ideDep);
                return true;
            }
            catch(Exception e) {
                //Aun no se corre el servicio de alertas
                String ee = e.ToString();
                return false;

            }

          //  return false;


        }

        private String obtenerHTML(int area, List<ORIDetCompendio> listaPlazos)
        { 
            StringBuilder html = new StringBuilder("");
            DateTime d1 = DateTime.Now;
            
            var detalleList = (
              from actor in db.ORIDetSoliActor
              join detalle in db.ORIDetSolicitud on new { actor.nIdeSolicitud, actor.nSeqPaso } equals new { detalle.nIdeSolicitud, detalle.nSeqPaso }
              join solicitud in db.ORIMaeSolicitud on actor.nIdeSolicitud equals solicitud.nIdeSolicitud
              join programa in db.ORIDetCompendio on solicitud.nIdePrograma equals programa.nIdeDetalle
              join clase in db.ORIDetCompendio on solicitud.nIdeClaseSolicitud equals clase.nIdeDetalle
              join tipo in db.ORIDetCompendio on solicitud.nTipoSolic equals tipo.nIdeDetalle
              join estadoDetalle in db.ORIDetCompendio on detalle.nIdeEstado equals estadoDetalle.nIdeDetalle
              join persona in db.ORIMaePersona on solicitud.nIdePersonSolicita equals persona.nIdePersona
              join afectado in db.ORIMaePersona on solicitud.nIdePersonAfectado equals afectado.nIdePersona
              where (actor.nIdeDep == area) &&
                    (actor.nIdeTipoActor == 2) &&
                    (actor.dtFecDerivacion == null) 
              select new SolicitudBandeja()
              {
                  //fechaRecepcion =detalle.dtFecReg,
                  tipoSolicitud = solicitud.nIdeClaseSolicitud,
                  plazo = detalle.nPlazo.Value,
                  nIdeSolicitud = actor.nIdeSolicitud,
                  nIdeDep = solicitud.nIdeDep,
                  clase = clase.vNomDetalle,
                  tipo = tipo.vNomCorto,
                  programa = programa.vNomCorto,
                  solicitante = persona.vNumDocum + " " + persona.vPriNombre + " " + persona.vPriApellido,
                  afectado = afectado.vNumDocum + " " + afectado.vPriNombre + " " + afectado.vPriApellido,
                  nAnnSolicitud = solicitud.nAnnSolicitud,
                  fechaEntrada = actor.dtFecRecepcion,
                  fechaRecepcion = actor.dtFecRecFisica,
                  fechaLectura = actor.dtFecLectura,
                  nSeqActor = actor.nSeqActor,
                  nSeqPaso = actor.nSeqPaso,
                  nNumSolicitud = solicitud.nNumCorrelativo,
                  estado = estadoDetalle.vNomCorto
              }).Distinct();

            List<SolicitudBandeja> list =  detalleList.Distinct().OrderBy(m => m.nIdeSolicitud).ToList();

            if (list.Count > 0)
            {



                html.Append("<div align='center'><table width='100%' style='border-collapse:collapse; font-family:Helvetica; font-size: 8pt; font-style:normal;'>");
                html.Append("<tr style='background-color:#b1074b'>");
                html.Append("<td style='border: 1px solid black;'>#</td>");
                html.Append("<td style='border: 1px solid black;'>Dias de atrazo</td>");
                html.Append("<td style='border: 1px solid black;'>Nro Solicitud</td>");
                html.Append("<td style='border: 1px solid black;'>Solicitante/Afectado</td>");
                html.Append("<td style='border: 1px solid black;'>Programa</td>");
                html.Append("<td style='border: 1px solid black;'>Tipo de solicitud</td>");
                html.Append("<td style='border: 1px solid black;'>Motivo de solicitud</td>");
                //html.Append("<td>Para</td>");
                html.Append("<td style='border: 1px solid black;'>Fecha de Recepción</td>");
                //html.Append("<td>Actor</td>");
                html.Append("</tr>");

            }
            else
            {
                html.Append("No existen solicitudes fuera de plazo");
                return html.ToString();

            }
            int filas = 0;
            foreach (SolicitudBandeja s in list) {



                    TimeSpan t = d1 - s.fechaEntrada.Value;
                    double NrOfDays = t.TotalDays;
                    decimal plazo = obtenerPlazo(s.tipoSolicitud.Value, listaPlazos);
                    decimal diasAtrazo = (int)NrOfDays - plazo;
                    if (diasAtrazo >= 0)
                    {
                        filas++;
                        html.Append("<tr >");
                        html.Append("<td style='border: 1px solid black;'>").Append(filas).Append("</td>");
                        html.Append("<td style='border: 1px solid black;' align='center'>").Append(diasAtrazo.ToString()).Append("</td>");
                        html.Append("<td style='border: 1px solid black;' nowrap='norwrap'>").Append(String.Format("{0:000}", s.nIdeDep)).Append("-").Append(String.Format("{0:0000}", s.nAnnSolicitud)).Append("-").Append(s.clase.Substring(0, 3)).Append("-").Append(String.Format("{0:000000}", s.nNumSolicitud)).Append("</td>");
                        html.Append("<td style='border: 1px solid black;' nowrap='norwrap'>").Append(s.solicitante).Append("/<br/>").Append(s.afectado).Append("</td>");
                        html.Append("<td style='border: 1px solid black;' nowrap='norwrap'>").Append(s.programa).Append("</td>");
                        html.Append("<td style='border: 1px solid black;' nowrap='norwrap'>").Append(s.clase).Append("</td>");
                        html.Append("<td style='border: 1px solid black;' nowrap='norwrap'>").Append(s.tipo).Append("</td>");
                        html.Append("<td style='border: 1px solid black;' nowrap='norwrap'>").Append(String.Format("{0:dd/MM/yyyy HH:mm}", s.fechaEntrada)).Append("</td>");
                        html.Append("</tr>");
                    }
            
            }
            html.Append("</table></div>");
              
            if(filas==0)
            {   
                html=new StringBuilder("No existen solicitudes fuera de plazo");
                return html.ToString();

            }

            return html.ToString();

        }


        private decimal obtenerPlazo(decimal claseSolicitud, List<ORIDetCompendio> listaPlazos)
        {
            ORIDetCompendio plazo = listaPlazos.Find(r => r.vCodElemento == claseSolicitud.ToString());

            return Int32.Parse( plazo.vDesRef1);
        }


        private void actualizarLogAlerta(int correos) {

            ORIMaeLogAlerta alerta = new ORIMaeLogAlerta();
            alerta.dFecReg = DateTime.Today;
            alerta.vCodError = "0";
            alerta.vDescError = "EXITO:" + correos;
//            alerta.
            db.ORIMaeLogAlerta.AddObject(alerta);
            db.SaveChanges();



        }
    }



}